/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cfs.controller;

import cfs.databean.CFSTransaction;
import cfs.databean.Customer;
import cfs.databean.Datapoint;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import cfs.databean.Fund;
import cfs.databean.FundPriceHistory;
import cfs.databean.Position;
import cfs.helper.Helper;
import cfs.helper.TransactionTypes;
import cfs.model.FundDAO;
import cfs.model.FundPriceHistoryDAO;
import cfs.model.Model;
import cfs.model.PositionDAO;
import cfs.model.TransactionDAO;
import javax.servlet.http.HttpSession;
import org.mybeans.dao.DAOException;

/**
 * 
 * @author danny seow
 */
public class ViewFundAction extends Action {
	private FundDAO fundDAO;
	private FundPriceHistoryDAO fundPriceDAO;
	private PositionDAO positionDAO;
	private TransactionDAO transactionDAO;

	public ViewFundAction(Model model) {
		fundDAO = model.getFundDao();
		fundPriceDAO = model.getFundHistoryDao();
		positionDAO = model.getPositionDao();
		transactionDAO = model.getTransactionDao();
	}

	@Override
	public String getName() {
		return "viewFund.do";
	}

	@Override
	public String perform(HttpServletRequest request) {
		String selectedFund = request.getParameter("selectedFund");
		List<String> errors = new ArrayList<String>();
		request.setAttribute("errors", errors);
		try {

			// Fetching the values from the database
			int selectedFundInt = Integer.parseInt(selectedFund);
			Fund fund = fundDAO.lookup(selectedFundInt);
			String userShare = "0";
			String userAvaShare = "0";

			if (fund == null) {
				errors.add("No Fund item found");
			}
			if (errors.size() > 0)
				return "ViewFundList.jsp";

			ArrayList<FundPriceHistory> fundHistoryList = fundPriceDAO
					.getFundByType(selectedFundInt);
			FundPriceHistoryManager fphm = new FundPriceHistoryManager();
			String formatedPriceDifferences = "";
			String formatedMaxPrice = "Not initiated yet";
			String formatedMinPrice = "Not initiated yet";
			double volatility = 0.0;
			String volatilityString = "Not initiated yet";
			if (fundHistoryList != null && fundHistoryList.size() > 0) {
				formatedPriceDifferences = fphm
						.getLatestDifference(fundHistoryList);
				formatedMaxPrice = fphm
						.getMaximumOverPeriod(fundHistoryList, 7);
				formatedMinPrice = fphm
						.getMinimumOverPeriod(fundHistoryList, 7);
				volatility = fphm.calculateVioliatity(fundHistoryList, 1);
				volatilityString = fphm.formatDecimal(volatility);
				// Object[][] dataSet = fphm.populateChart(fundHistoryList);
			}
			ArrayList<FundPriceHistory> lastWeekFunds = new ArrayList<FundPriceHistory>();
			ArrayList<Datapoint> dataList = new ArrayList<Datapoint>();
			int q = 0;
			for (int x = 0; x < fundHistoryList.size(); x++) {
				Datapoint dp = new Datapoint(fundHistoryList.get(x));
				dataList.add(dp);
				request.setAttribute("latestPrice", (fundHistoryList.get(0)
						.getPrice() * 0.01));
			}
			while (q < 8) {
				if (fundHistoryList.size() > q) {
					lastWeekFunds.add(fundHistoryList.get(q));
				} else {
					FundPriceHistory fp = new FundPriceHistory();
					fp.setFund_id(selectedFundInt);
					fp.setPrice(0);
					fp.setPrice_date(null);
					lastWeekFunds.add(fp);
				}
				q++;
			}

			// Get the user position;
			double retrieveTotalEarnings = 0.0;
			if (request.getSession().getAttribute("user") != null) {
				Customer user = (Customer) request.getSession().getAttribute(
						"user");
				Position[] userPosition = positionDAO.getPosition(
						user.getCustomer_id(), selectedFundInt);
				if (userPosition != null && userPosition.length == 1) {
					userShare = Helper.formatWith3Decimal((userPosition[0]
							.getShares() * 0.001));
					userAvaShare = Helper.formatWith3Decimal((userPosition[0]
							.getAvailableshares() * 0.001));
					retrieveTotalEarnings = retrieveTotalEarnings(
							userPosition[0].getShares(), fundHistoryList);
				}

				double totalinvestedAmount = retrieveInvestedAmount(
						selectedFundInt, user.getCustomer_id());
				double totalProfit = retrieveSoldAmount(selectedFundInt,
						user.getCustomer_id());
				request.setAttribute("retrieveTotalEarnings",
						retrieveTotalEarnings);
				request.setAttribute("investedAmount", totalinvestedAmount);
				request.setAttribute("totalProfit", totalProfit);
				request.setAttribute("userAvaShare", userAvaShare);
				request.setAttribute("userShare", userShare);
			}

			// HttpSession session = request.getSession();
			request.setAttribute("dataList", dataList);
			request.setAttribute("volatility", volatilityString);
			request.setAttribute("maxPrice", formatedMaxPrice);
			request.setAttribute("minPrice", formatedMinPrice);
			request.setAttribute("fund", fund);
			request.setAttribute("fundHistoryList", lastWeekFunds);
			request.setAttribute("fundPriceDiff", formatedPriceDifferences);
			return "ViewFundPage.jsp";
		} catch (Exception e) {
			errors.add("Error in retriving data");
			return "ViewFundPage.jsp";
		}
	}

	private double retrieveInvestedAmount(int fund_id, int customer_id)
			throws DAOException {
		List<CFSTransaction> cfList = transactionDAO.getFundTransactionList(
				fund_id, customer_id, TransactionTypes.BUY_FUND);
		long totalAmount = 0;
		if (cfList != null && cfList.size() > 0) {
			for (int z = 0; z < cfList.size(); z++) {
				totalAmount = totalAmount + cfList.get(z).getAmount();
			}
		}
		return (totalAmount * 0.01);
	}

	private double retrieveSoldAmount(int fund_id, int customer_id)
			throws DAOException {
		List<CFSTransaction> cfList = transactionDAO.getFundTransactionList(
				fund_id, customer_id, TransactionTypes.SELL_FUND);
		long totalAmount = 0;
		if (cfList != null && cfList.size() > 0) {
			for (int z = 0; z < cfList.size(); z++) {
				totalAmount = totalAmount + cfList.get(z).getAmount();
			}
		}
		return (totalAmount * 0.01);
	}

	private double retrieveTotalEarnings(long shares,
			ArrayList<FundPriceHistory> fundHistoryList) throws DAOException {
		double currentValue = 0;
		if (fundHistoryList != null && fundHistoryList.size() > 0) {
			for (int z = 0; z < fundHistoryList.size(); z++) {
				double priceOfFund = fundHistoryList.get(0).getPrice() * 0.01;
				double HoldingShares = shares * 0.001;
				currentValue = HoldingShares * priceOfFund;
				break;
			}
		}
		return Helper.valueRounding(currentValue, 2);
	}

}
